import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

class Solution {
    public String getString(int[] point) {
        return point[0] + "-" + point[1];
    }

    public boolean onLine(int[] p1, int[] p2, int[] p3) {
        int x1 = p1[0], y1 = p1[1];
        int x2 = p2[0], y2 = p2[1];
        int x3 = p3[0], y3 = p3[1];
        // 计算向量叉积
        return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1) == 0;
    }

    public int maxPoints(int[][] points) {

        int length = points.length;
        if (length == 1) {
            return 1;
        }
        Map<String, Map<String, List<String>>> map = new HashMap<>();
        for (int i = 0; i < length; i++) {
            for (int j = i + 1; j < length; j++) {
                // System.out.println(Arrays.deepToString(points[i]) + " " +
                // Arrays.deepToString(points[j]));
                map.putIfAbsent(getString(points[i]), new HashMap<>());
                map.get(getString(points[i])).putIfAbsent(getString(points[j]), new ArrayList<>());
                map.get(getString(points[i])).get(getString(points[j])).add(getString(points[i]));
                map.get(getString(points[i])).get(getString(points[j])).add(getString(points[j]));
                for (int l = 0; l < length; l++) {
                    if (!Arrays.equals(points[l], points[i]) && !Arrays.equals(points[l], points[j])) {
                        if (onLine(points[i], points[j], points[l])) {
                            map.get(getString(points[i])).get(getString(points[j])).add(getString(points[l]));

                        }
                    }
                }
            }

        }
        AtomicInteger max = new AtomicInteger();
        map.entrySet().forEach(kv1 -> {
            kv1.getValue().entrySet().forEach(kv2 -> {
                System.out.println(kv2.getValue());
                max.set(Math.max(max.get(), kv2.getValue().size()));
            });
        });
        return max.get();
    }
}